import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.Collator;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class E2 {
  /**
   * open BufferedReader on specified file with specified charset
   * @param file
   * @param charset
   * @return
   * @throws FileNotFoundException 
   * @throws UnsupportedEncodingException 
   */
  private static BufferedReader bufferedReader(String file, String charset) throws FileNotFoundException, UnsupportedEncodingException {
    // if this throw exception just throw it out
    FileInputStream fis = new FileInputStream(file);
    // this constructor can throw UnsupportedEncodingException
    // however, in this case we are sure that UTF8 is supported encoding
    InputStreamReader isr = new InputStreamReader(fis, charset);
    // this constructor does not throws exception
    return new BufferedReader(isr);
  }

  /**
   * open PrintWriter on specified file with specified charset
   * @param file
   * @param charset
   * @return
   * @throws FileNotFoundException 
   * @throws UnsupportedEncodingException 
   */
  private static PrintWriter printWriter(String file, String charset) throws FileNotFoundException, UnsupportedEncodingException {
    // if this throw exception just throw it out
    FileOutputStream fos = new FileOutputStream(file);
    // this constructor can throw UnsupportedEncodingException
    // however, in this case we are sure that UTF8 is supported encoding
    OutputStreamWriter osw = new OutputStreamWriter(fos, charset);
    // this constructor does not throws exception
    BufferedWriter bw = new BufferedWriter(osw);
    // this constructor does not throws exception
    return new PrintWriter(bw);
  }

  /**
   * @param args
   * @throws FileNotFoundException 
   * @throws UnsupportedEncodingException 
   */
  /**
   * @param args
   * @throws FileNotFoundException
   * @throws UnsupportedEncodingException
   */
  public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException, IOException {    
    Collator collator = Collator.getInstance();
    collator.setStrength(Collator.PRIMARY);
    // we are going to use set to holder words, why?
    Set<String> set = new TreeSet<String>(collator);
    // this constructor does not throws exception
    Scanner scanner = new Scanner(bufferedReader("words.txt","UTF8"));
    // put all reading code in try finally so we can release resources at the end
    try {
      // use scanner with its default settings... like delimiter is any whitespace character
      while (scanner.hasNext("\\w+")) {
        String next = scanner.next("\\w+");
        set.add(next);
      }
    } finally {
      // this will close at the end FileInputStream opened on integers.txt
      scanner.close();
    }

    BufferedReader br = bufferedReader("text.txt","UTF8");
    PrintWriter pw = null;
    String line = null;
    // do the reading and writing in try finally block
    try {
      // this operation may throw exception
      // in this case pw variable will be null
      // but we need to close BufferedReader - this will be done in finally block 
      pw = printWriter("result.txt","UTF8");
      // print put words that are going to be replaced
      System.out.println("words that are going to be replaced: " + set);
      //build the regex
      String regex = "(?i)";
      String or = "";
      for (String word : set) {
        regex = regex + or + word;
        or = "|";
      }
      System.out.println("regex that is going to be used: " + regex);
      Pattern pattern = Pattern.compile(regex);
      while ((line = br.readLine()) != null) {
        Matcher m = pattern.matcher(line);
        while(m.find()) {
          String matched = m.group();
          char[] chars = new char[matched.length()];
          Arrays.fill(chars, '*');
          String replacement = new String(chars);
          line = line.replace(matched, replacement);
        }
        pw.println(line);
      }
    } finally {
      if (pw != null) {
        // PrintWriter, even if its a stream does not throws exceptions
        pw.close();
        // so we need to check whether close (and implicitly flush) was successful
        if (pw.checkError()) {
          System.err.println("result.txt may not be in good condition");
        }
      }
      br.close();
    }
  }

}
